﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using ZK.Common;

namespace ZK.HardWareBLL
{
    public class SocketServerBLL :BaseBLL
    {

        private Socket listenSocket;
        List<Socket> clientsockets = new List<Socket>();
        HaredWareCommonM haredWareCommonM;

        public SocketServerBLL(HaredWareCommonM hWC) {
            DelegateHelper.A9Event += a9Event1;
            haredWareCommonM = hWC;
            creatTcpServer();
        }

        private void a9Event1(byte[] weight)
        {
            socketServerSendMsgAll(weight);
        }

        string getLocalIp()
        {
            string hostName = Dns.GetHostName(); // 获取当前机器的名字
            IPAddress[] addresses = Dns.GetHostAddresses(hostName); // 获取机器的IP地址

            foreach (IPAddress address in addresses)
            {
                if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) // 筛选出IPv4地址
                {
                    return address.ToString();
                }
            }
            return "127.0.0.1";
        }

        private void creatTcpServer()
        {
            //第一步：调用socket()函数创建一个用于通信的套接字
            listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            ////第二步：给已经创建的套接字绑定一个端口号，这一般通过设置网络套接口地址和调用Bind()函数来实现
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(getLocalIp()), int.Parse(this.haredWareCommonM.Port));

            //IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 5005); // 端口号需要是未被使用的
            //listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);


            try
            {
                listenSocket.Bind(endPoint);
            }
            catch (Exception ex)
            {
                Common.Log4.LogManage.WriteErr(ex.ToString());
                return;
            }

            //第三步：调用listen()函数使套接字成为一个监听套接字
            listenSocket.Listen(10);
            //开启一个线程监听
            Task.Run(new Action(() =>
            {
                ListenConnection();
            }
                ));
        }

        private void ListenConnection()
        {
            while (true)
            {
                Socket clientSocket = listenSocket.Accept();

                string ip = clientSocket.RemoteEndPoint.ToString();
                clientsockets.Add(clientSocket);
                Task.Run(() => ReceiveMsg(clientSocket));

            }


        }
        void socketServerSendMsgAll(byte[] by)
        {
            foreach (var item in this.clientsockets)
            {
                item.Send(by);
            }
        }

        /// <summary>
        /// 接收方法
        /// </summary>
        /// <param name="clientSocket"></param>
        private void ReceiveMsg(Socket clientSocket)
        {
            while (true)
            {
                //定义一个2M的缓冲区
                byte[] buffer = new byte[1024 * 1024 * 2];

                int length = -1;
                try
                {
                    length = clientSocket.Receive(buffer);
                }
                catch (Exception)
                {

                    //客户端下线了

                    //更新在线列表
                    string ip = clientSocket.RemoteEndPoint.ToString();
                    clientsockets.Remove(clientSocket);

                    break;
                }

                if (length == 0)
                {
                    //客户端下线了
                    clientsockets.Remove(clientSocket);
                    //更新在线列表
                    string ip = clientSocket.RemoteEndPoint.ToString();
                    break;
                }


                if (length > 0)
                {
                }
            }
        }
    }
}
